#ifndef RTU_MASTER_HPP
#define RTU_MASTER_HPP

#include "ModbusMaster.hpp"

namespace Modbus {

class RTUMaster : public Master {
public:
    enum class ErrorNumber : int {
        None = 0,
        CRCError,
        Timeout,
        IOError,
        BufferError,
        SystemError,
        NullPortable,
    };
public:
    class PortableStrategy {
    public:
        virtual ~PortableStrategy() = default;
        virtual bool send(unsigned char chr) = 0;
        virtual bool cut(void) = 0;
        virtual bool wait(int interval) = 0;
        virtual bool lock(void) = 0;
        virtual bool unlock(void) = 0;
    };
public:
    explicit RTUMaster(char *buffer,unsigned int buffer_size,PortableStrategy *portable_strategy);
    virtual ~RTUMaster() = default;

    virtual unsigned int sendRequest(int slave_address,const char *buffer,unsigned int length,int timeout = -1);
    virtual unsigned int receiveResponse(int slave_address,char *buffer,unsigned int length,int timeout = -1);

    virtual bool feed(char chr);
    virtual bool cut(void);

    virtual int getErrorNumber(void);
protected:
    PortableStrategy *portable_strategy = nullptr;
    int error_number = 0;
    struct {
        char *buffer = nullptr;
        unsigned int buffer_size = 0;
        unsigned int rx_size = 0;
        unsigned int payload_offset = 0;
        unsigned int payload_size = 0;
    } rx_buffer_information;
};

}

#endif
